package cn.fl.system.service.impl;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;

import cmm.comm.facade.framework.api.ISysDictionaryApiService;
import cmm.comm.facade.framework.dto.SysDictionaryDTO;
import cmm.comm.facade.upload.constant.SysUlFilesRecConstant;
import cmm.mid.core.framework.page.KeyValueVO;
import cmm.mid.core.framework.page.Pager;
import cmm.user.facade.system.api.ISysOrgApiService;
import cmm.user.facade.system.dto.SysOrgDTO;
import cn.cmm.base.framework.constant.BaseConstant;
import cn.cmm.base.framework.constant.BaseExceptionConstant;
import cn.cmm.base.framework.exception.BaseException;
import cn.cmm.base.framework.utils.BaseLogUtils;
import cn.cmm.base.framework.utils.CollectionUtils;
import cn.cmm.base.framework.utils.DateUtils;
import cn.cmm.base.framework.utils.StringUtils;
import cn.cmm.cache.framework.utils.PropertiesCacheUtils;
import cn.fl.framework.base.context.CurrentThreadContext;
import cn.fl.framework.constant.DictionaryConstant;
import cn.fl.system.condition.SysBkAccInfoQueryCondition;
import cn.fl.system.condition.SysBkInfoQueryCondition;
import cn.fl.system.constant.SysBkInfoConstant;
import cn.fl.system.dto.SysBkAccInfoDTO;
import cn.fl.system.dto.SysBkInfoDTO;
import cn.fl.system.service.ISysBkAccInfoService;
import cn.fl.system.service.ISysBkInfoApiService;
import cn.fl.system.transform.SysBkAccInfoVOTransform;
import cn.fl.system.transform.SysBkInfoVOTransform;
import cn.fl.system.vo.SysBkAccInfoVO;
import cn.fl.system.vo.SysBkInfoVO;
import cn.lb.framework.poi.excel.ExcelExportUtil;
import cn.lb.framework.poi.excel.entity.ExportParams;
import cn.lb.framework.poi.excel.entity.enmus.ExcelType;
import cn.lb.framework.poi.excel.export.styler.ExcelExportStylerBorderImpl;

@Service
public class SysBkAccInfoServiceImpl implements ISysBkAccInfoService {

	/**
	 * 日志
	 */
	private static final Logger logger = LoggerFactory.getLogger(SysBkAccInfoServiceImpl.class);
	
	/**
	 * 系统银行信息API暴露服务
	 */
	@Autowired
	private ISysBkInfoApiService sysBkInfoApiService;
	
	@Autowired
	private ISysOrgApiService sysOrgApiService;
	
	/**
	 * 本地数据字典服务
	 */
	@Autowired
	private ISysDictionaryApiService sysDictionaryApiService;

	@Override
	public SysBkAccInfoVO selectById(Long id) throws BaseException{
		if(StringUtils.isEmpty(id)){
			BaseLogUtils.info(logger, "selectById", "根据主键查询银行账号信息失败,主键参数为空.ID:"+id,CurrentThreadContext.getCurrentUserName());
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600,BaseExceptionConstant.BASE_EXCEPTION_CODE_600_NAME);
		};
		SysBkAccInfoDTO dto = this.sysBkInfoApiService.selectSysBkAccInfoById(id,CurrentThreadContext.getCurrentSysCd(),CurrentThreadContext.getCurrentOrgCd());
		BaseLogUtils.info(logger, "selectById", "根据主键查询银行账号信息成功.DATA:"+JSONObject.toJSONString(dto),CurrentThreadContext.getCurrentUserName());
		return SysBkAccInfoVOTransform.toVO(dto);
	}

	@Override
	public Long add(SysBkAccInfoVO entity) throws BaseException{
		if(null == entity){
			BaseLogUtils.info(logger, "add", "新增银行账号失败,银行对象参数为空.DATA:"+JSONObject.toJSONString(entity),CurrentThreadContext.getCurrentUserName());
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600,BaseExceptionConstant.BASE_EXCEPTION_CODE_600_NAME);
		}
		return this.sysBkInfoApiService.addSysBkAccInfo(SysBkAccInfoVOTransform.toDTO(entity));
	}

	@Override
	public boolean modify(SysBkAccInfoVO entity) throws BaseException{
		if(null == entity){
			BaseLogUtils.info(logger, "modify", "修改银行账号失败,银行对象参数为空.DATA:"+JSONObject.toJSONString(entity),CurrentThreadContext.getCurrentUserName());
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600,BaseExceptionConstant.BASE_EXCEPTION_CODE_600_NAME);
		};
		return this.sysBkInfoApiService.modifySysBkAccInfo(SysBkAccInfoVOTransform.toDTO(entity));
	}

	@SuppressWarnings("unchecked")
	@Override
	public Pager searchListPage(Pager page) throws BaseException{
		if(null == page){
			page = new Pager();
		}
		page = this.sysBkInfoApiService.searchSysBkAccInfoListPage(page,CurrentThreadContext.getCurrentSysCd(),CurrentThreadContext.getCurrentOrgCd());
		List<SysBkAccInfoDTO> resultList = (List<SysBkAccInfoDTO>) page.getResultList();
		page.setResultList(SysBkAccInfoVOTransform.toVOList(resultList));
		return page;
	}
	
	@Override
	public List<KeyValueVO> searchBkAccTypCdList() throws BaseException {
		return this.getKvList(DictionaryConstant.CODE_GRP_ACC_TYP_CD);
	}
	
	/**
	 * 根据字典中代码组值获取组员集合
	 * @param grpCd 代码组值
	 * @return 集合
	 */
	@Override
	public List<KeyValueVO> getKvList(String grpCd){
		List<KeyValueVO> kvList = new ArrayList<>();
		try {
			List<SysDictionaryDTO> sysDictionaryDTOList = this.sysDictionaryApiService.searchGroup(CurrentThreadContext.getCurrentSysCd(), CurrentThreadContext.getCurrentOrgCd(), grpCd);
			if(CollectionUtils.isNotEmpty(sysDictionaryDTOList)){
				for (SysDictionaryDTO sysDictionaryDTO : sysDictionaryDTOList) {
					KeyValueVO keyValueVO = new KeyValueVO();
					keyValueVO.setKey(sysDictionaryDTO.getCode());
					keyValueVO.setValue(sysDictionaryDTO.getCodeNm());
					kvList.add(keyValueVO);
				}
			}
		} catch (BaseException e) {
			BaseLogUtils.info(logger, "getKvList", "获取字典项组"+grpCd+"失败.ERROR:"+e.getMessage(), CurrentThreadContext.getCurrentUserName());
		} catch (Exception e) {
			BaseLogUtils.error(logger, "getKvList", "获取字典项组"+grpCd+"失败,系统错误.ERROR:"+e.getMessage(), CurrentThreadContext.getCurrentUserName());
		}
		return kvList;
	}


	@Override
	public boolean enAbleSysBkAccInfo(Long id) throws BaseException {
		if(null == id){
			BaseLogUtils.info(logger, "enAbleSysBkAccInfo", "启用银行账号失败,主键参数为空.ID:"+id, CurrentThreadContext.getCurrentUserName());
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600,BaseExceptionConstant.BASE_EXCEPTION_CODE_600_NAME);
		};
		return this.sysBkInfoApiService.enAbleSysBkAccInfo(id,CurrentThreadContext.getCurrentSysCd(),CurrentThreadContext.getCurrentOrgCd());
	}

	@Override
	public boolean disAbleSysBkAccInfo(Long id) throws BaseException {
		if(null == id){
			BaseLogUtils.info(logger, "disAbleSysBkAccInfo", "禁用银行账号失败,主键参数为空.ID:"+id, CurrentThreadContext.getCurrentUserName());
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600,BaseExceptionConstant.BASE_EXCEPTION_CODE_600_NAME);
		};
		return this.sysBkInfoApiService.disAbleSysBkAccInfo(id);
	}

	@Override
	public boolean removeByIds(List<Long> ids) throws BaseException {
		if(CollectionUtils.isEmpty(ids)){
			BaseLogUtils.info(logger, "removeByIds", "删除银行账号失败,主键参数为空.IDS:"+JSONObject.toJSONString(ids), CurrentThreadContext.getCurrentUserName());
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600,BaseExceptionConstant.BASE_EXCEPTION_CODE_600_NAME);
		};
		return sysBkInfoApiService.removeSysBkAccInfoByIds(ids);
	}

	@Override
	public List<KeyValueVO> searchSysOrgByOrgLvl(Long orgLvl)
			throws BaseException {
		if(StringUtils.isEmpty(orgLvl)){
			BaseLogUtils.info(logger, "searchSysOrgByOrgLvl", "查询账号添加时平台选择项失败,组织架构级别参数为空.ORGLVL:"+orgLvl, CurrentThreadContext.getCurrentUserName());
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600,BaseExceptionConstant.BASE_EXCEPTION_CODE_600_NAME);
		};
		List<SysOrgDTO> sysOrgDTOList = sysOrgApiService.searchSysOrgByOrgPid(orgLvl,CurrentThreadContext.getCurrentSysCd());
		if(CollectionUtils.isEmpty(sysOrgDTOList)){
			BaseLogUtils.info(logger, "searchSysOrgByOrgLvl", "查询账号添加时平台选择项失败,查询结果为空.ORGLVL:"+orgLvl+"SYSCD:"+CurrentThreadContext.getCurrentSysCd(), CurrentThreadContext.getCurrentUserName());
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_601,BaseExceptionConstant.BASE_EXCEPTION_CODE_601_NAME);
		}
		
		List<KeyValueVO> kvList = new ArrayList<KeyValueVO>();
		for (SysOrgDTO sysOrgDTO : sysOrgDTOList) {
			KeyValueVO kv = new KeyValueVO();
			kv.setKey(String.valueOf(sysOrgDTO.getId()));
			kv.setValue(sysOrgDTO.getOrgNm());
			kvList.add(kv);
		}
		
		return kvList;
	}
	
	@Override
	public List<SysBkAccInfoVO> searchList(SysBkAccInfoQueryCondition qc)
			throws BaseException {
		if(null==qc) qc = new SysBkAccInfoQueryCondition();
		List<SysBkAccInfoDTO> sysBkAccInfoList = this.sysBkInfoApiService.searchSysBkAccInfoList(qc,CurrentThreadContext.getCurrentSysCd(),CurrentThreadContext.getCurrentOrgCd());
		return SysBkAccInfoVOTransform.toVOList(sysBkAccInfoList);
	}
	
	@Override
	public String exportBkAcc(List<Long> ids,HttpServletRequest request,HttpServletResponse response) throws BaseException {
		SysBkAccInfoQueryCondition qc = new SysBkAccInfoQueryCondition();
		//当前登录人所属架构代码取前四位设为查询条件
		qc.setOrgCd(CurrentThreadContext.getCurrentOrgCd().substring(0, 4));
		
		if(CollectionUtils.isNotEmpty(ids)){
			qc.setIds(ids);
		}
		List<SysBkAccInfoVO> bkAccList = this.searchList(qc);
		String path = "";
		try {
			if(CollectionUtils.isNotEmpty(bkAccList)){
				path = this.exportBkAccInfoToExcel(bkAccList, request, response);
			}
		} catch (Exception e) {
			BaseLogUtils.error(logger, "-", "异常", e);
		}
		return path;
	}
	
	@Override
	public List<SysBkInfoVO> searchOpenBkInfo() throws BaseException {
		SysBkInfoQueryCondition qc = new SysBkInfoQueryCondition();
		qc.setIsValid(BaseConstant.IS_YESNO_YES);
		List<SysBkInfoDTO> bkList = this.sysBkInfoApiService.searcheOpenBkInfo(qc,CurrentThreadContext.getCurrentSysCd(),CurrentThreadContext.getCurrentOrgCd());
		return SysBkInfoVOTransform.toVOList(bkList);
	}
	
	//*******************************私有方法**********************************/
	
	private String exportBkAccInfoToExcel(List<SysBkAccInfoVO> voList,HttpServletRequest request,HttpServletResponse response)throws BaseException{
		ExportParams params = new ExportParams("银行账号信息", "银行账号", ExcelType.XSSF);
        params.setColor(HSSFColor.BRIGHT_GREEN.index);//表头颜色
        params.setStyle(ExcelExportStylerBorderImpl.class);
		XSSFWorkbook workbook = (XSSFWorkbook)ExcelExportUtil.exportExcel(params,SysBkAccInfoVO.class, voList);
		//String path = PropertiesCacheUtils.getProperty(SysUlFilesRecConstant.SYS_FILE_UPLOAD_ROOT_PATH) + SysBkInfoConstant.SYS_EXPORT_ACC_SAVE_DIR;
		String path = SysBkInfoConstant.SYS_EXPORT_ACC_SAVE_DIR;
		path = this.getServerFilePath(path);
		path = path + System.currentTimeMillis() + ".xlsx";
        //String path="C:/ExportBkAccTest/export-bkAccInfo.xlsx";
        FileOutputStream fos = null;
        try {
            fos=new FileOutputStream(path);
            workbook.write(fos);
            fos.flush();
        } catch (FileNotFoundException e) {
            BaseLogUtils.info(logger, "exportBkAccInfoToExcel", e.getMessage());
            throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_405, BaseExceptionConstant.BASE_EXCEPTION_CODE_405_NAME);
        } catch (Exception e) {
            BaseLogUtils.info(logger, "exportBkAccInfoToExcel", e.getMessage());
            throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_700, BaseExceptionConstant.BASE_EXCEPTION_CODE_700_NAME);
        }finally {
            try {
            	if(null!=fos){
            		fos.close();
            	}
            } catch (IOException e) {
			BaseLogUtils.error(logger, "-", "异常", e);
            }
        }
        //this.sysUlFilesRecService.fileDownload(SysBkInfoConstant.SYS_EXPORT_ACC_FILE_NAME, path, request, response);
        BaseLogUtils.info(logger, "exportBkAccInfoToExcel", "导出账户excel,文件根路径.serverFilePath:"+path);
		String serverPath = path.replace(PropertiesCacheUtils.getProperty(SysUlFilesRecConstant.SYS_FILE_UPLOAD_ROOT_PATH), PropertiesCacheUtils.getProperty(SysUlFilesRecConstant.SYS_FILE_UPLOAD_SERVER_PATH));
		BaseLogUtils.info(logger, "exportBkAccInfoToExcel", "导出账户excel,返回服务器路径.serverPath:"+serverPath);
        return serverPath;
        //return SysUlFilesRecConstant.SYS_FILE_UPLOAD_SERVER_PATH + path;
	}
	/**
	 * 创建文件服务器保存路径
	 */
	private String getServerFilePath(String filePath)throws BaseException{
		String prifixPath = PropertiesCacheUtils.getProperty(SysUlFilesRecConstant.SYS_FILE_UPLOAD_ROOT_PATH);//根目录
		StringBuffer savePath = new StringBuffer(prifixPath);//最终保存路径
		if(!savePath.toString().endsWith(SysUlFilesRecConstant.SYS_FILE_PATH_SLASH)){//判断是否以"/"结尾,不是加入斜杠
    		savePath.append(SysUlFilesRecConstant.SYS_FILE_PATH_SLASH);
    	}
		savePath.append(PropertiesCacheUtils.getProperty(SysUlFilesRecConstant.UPLOAD_COSTOMER_PATH));//自定义代码-其中包括系统代码
		if(StringUtils.isNotEmpty(filePath)){//如果不等于空则加入
			if(filePath.startsWith(SysUlFilesRecConstant.SYS_FILE_PATH_SLASH)){//判断是否以"/"开头
				savePath.append(filePath.substring(1));
			}else{
				savePath.append(filePath);
			}
			
		}
		if(!savePath.toString().endsWith(SysUlFilesRecConstant.SYS_FILE_PATH_SLASH)){//判断是否以"/"结尾
    		savePath.append(SysUlFilesRecConstant.SYS_FILE_PATH_SLASH);
    	}
		String currentTime = DateUtils.formatDateToString(new Date(), DateUtils.YYYYMMDD);
		savePath.append(currentTime);
		savePath.append(SysUlFilesRecConstant.SYS_FILE_PATH_SLASH);
	    //检查目录
		File pathFile = new File(savePath.toString());
	    if (!pathFile.exists()) {
	    	BaseLogUtils.info(logger, "getServerFilePath", "文件保存服务器路径不存在需要创建.savePath:"+savePath);
	    	//文件夹不存 创建文件
	    	boolean createPath = pathFile.mkdirs();
	    	if(!createPath){
	    		BaseLogUtils.info(logger, "getServerFilePath", "创建文件保存服务器路径失败.savePath:"+savePath);
	    		throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600, "服务器附件目录未创建成功!");
	    	}
	    	BaseLogUtils.info(logger, "getServerFilePath", "创建文件保存服务器路径成功.savePath:"+savePath);
	    }
	    BaseLogUtils.info(logger, "getServerFilePath", "获取文件保存服务器路径.savePath:"+savePath);
	    return savePath.toString();
	    //TODO return "C:/home/";
	}

}
